﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using POSPlus.PrintManager.Core;
using POSPlus.MvcPassiveView;

namespace POSPlus.PrintManager
{
	public partial class PrintManagerView : Form, IPrintManagerView
	{
		#region Delegates and Events
		private event RemoveButtonEventHandler _removeButtonEvent;
		private event PrintSelectedButtonEventHandler _printSelectedEvent;
		private event PrintAllButtonEventHandler _printAllEvent;
		private event EditPrintJobEventHandler _editPrintJob;
		#endregion

		#region Private Members
		private ChangeRequestEvents _changeRequestedEvents;
		private List<IPrintJob> _printJobs;
		#endregion

		#region Constructors
		public PrintManagerView()
		{
			InitializeComponent();
			CreateListGroups();
			_changeRequestedEvents = new ChangeRequestEvents(this);
		}

		public PrintManagerView(Point location)
		{
			InitializeComponent();
			CreateListGroups();
			Location = location;
			_changeRequestedEvents = new ChangeRequestEvents(this);
		}

		public PrintManagerView(int x, int y)
		{
			InitializeComponent();
			CreateListGroups();
			Location = new Point(x, y);
			_changeRequestedEvents = new ChangeRequestEvents(this);
		}
		#endregion

		#region Public Properties
		public List<IPrintJob> PrintJobs
		{
			set 
			{
				_printJobs = value;
				ui_jobListView.Items.Clear();
				Dictionary<string, IPrintJob> dictJobs = new Dictionary<string, IPrintJob>();
				foreach (IPrintJob job in value)
				{
					if (!dictJobs.ContainsKey(job.JobName))
						dictJobs.Add(job.JobName, job);
					else if (dictJobs[job.JobName].Type != job.Type)
						dictJobs.Add(job.JobName, job);
					else
						dictJobs[job.JobName].Items += job.Items;
				}
				foreach (KeyValuePair<string, IPrintJob> job in dictJobs)
				{
					ListViewItem jobItem = new ListViewItem(job.Key);
					jobItem.SubItems.Add(job.Value.Items.ToString());
					jobItem.SubItems.Add(job.Value.Type);
					jobItem.Group = ParseGroup(job.Value.Type);
					ui_jobListView.Items.Add(jobItem);
				}
			}
			get
			{
				return _printJobs;
			}
		}
		#endregion

		#region Methods
		public void RegisterChangeRequestListener<T>(string propertyName, EventHandler<MvcPassiveView.PropertyChangeRequestEventArgs<T>> handler)
		{
			_changeRequestedEvents.RegisterListener<T>(propertyName, handler);
		}

		public void UnRegisterChangeRequestListener<T>(string propertyName, EventHandler<MvcPassiveView.PropertyChangeRequestEventArgs<T>> handler)
		{
			_changeRequestedEvents.UnRegisterListener<T>(propertyName, handler);
		}

		private ListViewGroup ParseGroup(String type)
		{
			if (type == "6UPSDF")
				return ui_jobListView.Groups["6UPSD"];
			if (type == "12UPSDF")
				return ui_jobListView.Groups["12UPSD"];
			return ui_jobListView.Groups[type];
		}

		private void GetPageCounts(List<String> types)
		{
			if (types.Count < 1)
			{
				ui_pageCountLabel.Visible = false;
				ui_runsLabel.Visible = false;
			}
			else
			{
				List<PrintJob> selectedJobs = new List<PrintJob>();
				foreach (String type in types)
				{
					foreach (PrintJob job in PrintJobs)
					{
						if (job.JobName == type)
						{
							selectedJobs.Add(job);
						}
					}
				}

				Dictionary<String, int> runsAndPages = new Dictionary<String, int>();
				foreach (PrintJob job in selectedJobs)
				{
					int pages = (int)Math.Ceiling(job.Items / double.Parse(job.Type.Split('U')[0]));
					if (!runsAndPages.ContainsKey(job.Type))
					{
						runsAndPages.Add(job.Type, pages);
					}
					else
					{
						runsAndPages[job.Type] += pages;
					}
				}

				int totalPages = 0;
				foreach (KeyValuePair<String, int> pair in runsAndPages)
				{
					totalPages += pair.Value;
				}

				ui_runsLabel.Text = "Runs: " + runsAndPages.Count;
				ui_pageCountLabel.Text = "Page Count: " + totalPages.ToString();
				ui_pageCountLabel.Visible = true;
				ui_runsLabel.Visible = true;
			}
		}

		private void CreateListGroups()
		{
			foreach (PrintTagTypes type in Enum.GetValues(typeof(PrintTagTypes)))
			{
				ui_jobListView.Groups.Add(new ListViewGroup(ShortStringEnum.GetStringValue(type), StringEnum.GetStringValue(type)));
			}
		}

		#region UI Events
		private void ui_printSelectedButton_Click(object sender, EventArgs e)
		{
			List<String> jobNames = new List<string>();
			foreach (ListViewItem selectedItem in ui_jobListView.SelectedItems)
				jobNames.Add(selectedItem.Text);

			if (_printSelectedEvent != null)
				_printSelectedEvent(this, new PrintEventArgs(jobNames));
		}	
	
		private void ui_removeButton_Click(object sender, EventArgs e)
		{
			List<String> jobNames = new List<string>();
			foreach (ListViewItem selectedItem in ui_jobListView.SelectedItems)
				jobNames.Add(selectedItem.Text);		

			if (_removeButtonEvent != null)
				_removeButtonEvent(this, new RemoveEventArgs(jobNames));
		}

		private void ui_printAll_Click(object sender, EventArgs e)
		{
			List<String> jobNames = new List<string>();
			foreach (ListViewItem item in ui_jobListView.Items)
				jobNames.Add(item.Text);

			if (_printAllEvent != null)
				_printAllEvent(this, new PrintEventArgs(jobNames));
		}

		private void ui_jobListView_SelectedIndexChanged(object sender, EventArgs e)
		{
			List<String> items = new List<String>();
			foreach (ListViewItem item in ui_jobListView.Items)
			{
				if (item.Selected)
					items.Add(item.Text);
			}
			GetPageCounts(items);
		}

		private void ui_jobListView_DoubleClick(object sender, EventArgs e)
		{
			string jobName = ui_jobListView.SelectedItems[0].SubItems[0].Text;
			if (_editPrintJob != null)
				_editPrintJob(jobName);
		}
		#endregion

		#endregion

		public event RemoveButtonEventHandler RemoveButton
		{
			add { _removeButtonEvent += value; }
			remove { _removeButtonEvent -= value; }
		}

		public event PrintSelectedButtonEventHandler PrintSelected
		{
			add { _printSelectedEvent += value; }
			remove { _printSelectedEvent -= value; }
		}

		public event PrintAllButtonEventHandler PrintAll
		{
			add { _printAllEvent += value; }
			remove { _printAllEvent -= value; }
		}

		public event EditPrintJobEventHandler EditPrintJob
		{
			add { _editPrintJob += value; }
			remove { _editPrintJob -= value; }
		}
	}
}
